package com.kitten.count.consumer;

import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.nacos.shaded.com.google.common.util.concurrent.RateLimiter;
import com.kitten.count.constant.MQConstants;
import com.kitten.count.domain.mapper.NoteCollectionDOMapper;
import com.kitten.count.domain.mapper.NoteCountDOMapper;
import com.kitten.count.domain.mapper.UserCountDOMapper;
import com.kitten.count.model.dto.AggregationCountCollectUnCollectNoteMqDTO;
import com.kitten.framework.common.utils.JsonUtils;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.apache.rocketmq.spring.annotation.RocketMQMessageListener;
import org.apache.rocketmq.spring.core.RocketMQListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.support.TransactionTemplate;

import java.util.List;


/**
 * @author kitten
 */
@Slf4j
@Component
@RocketMQMessageListener(consumerGroup = "kittenBook_group_" + MQConstants.TOPIC_COUNT_NOTE_COLLECT_2_DB,
    topic = MQConstants.TOPIC_COUNT_NOTE_COLLECT_2_DB
)
public class CountNoteCollect2DBConsumer implements RocketMQListener<String> {

    @Resource
    private NoteCollectionDOMapper noteCollectionDOMapper;

    private RateLimiter rateLimiter = RateLimiter.create(100);  // 100 qps

    @Resource
    private NoteCountDOMapper noteCountDOMapper;

    @Resource
    private UserCountDOMapper userCountDOMapper;

    @Autowired
    private TransactionTemplate transactionTemplate;


    @Override
    public void onMessage(String message) {
        rateLimiter.acquire();
        log.info("笔记收藏计数数据入库 consumer receive message: {}", message);

        List<AggregationCountCollectUnCollectNoteMqDTO> dtos = null;

        try {
            dtos = JsonUtils.parseList(message, AggregationCountCollectUnCollectNoteMqDTO.class);
        } catch (Exception e) {
            log.error("解析 JSON 字符串异常, {}", e);
        }

        if (CollectionUtil.isNotEmpty(dtos)) {
            dtos.forEach(dto -> {
                Long noteId = dto.getNoteId();
                Long creatorId = dto.getCreatorId();
                Integer count = dto.getCount();

                // 编程式事务
                transactionTemplate.execute(status -> {
                    try {
                        noteCountDOMapper.insertOrUpdateCollectTotalByNoteId(noteId, count);
                        userCountDOMapper.insertOrUpdateCollectTotalByUserId(creatorId, count);
                        return true;
                    } catch (Exception e) {
                        status.setRollbackOnly();
                        log.error("点赞计数数据入库异常, {}", e);
                        return false;
                    }
                });
            });
        }

    }

}
